package com.example.java_chatroom.api;

import com.example.java_chatroom.component.OnlineUserManger;
import com.example.java_chatroom.model.*;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

import java.io.IOException;
import java.util.List;

/**
 * @author Q
 * @create 2025-07-08-9:07
 */
@Component
public class WebSocketAPI extends TextWebSocketHandler {
    @Autowired
    private OnlineUserManger onlineUserManger;
    @Autowired
    private MessageSessionMapper messageSessionMapper;
    @Autowired
    private MessageMapper messageMapper;
    private ObjectMapper objectMapper = new ObjectMapper();
    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        //webSocket连接成功后自动调用
        System.out.println("[WebSocketAPI] 连接成功！");
        User user = (User) session.getAttributes().get("user");
        if(user == null) {
            return;
        }
        //上线
        onlineUserManger.online(user.getUserId(),session);
    }

    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        //webSocket收到消息后自动调用
        System.out.println("[WebSocketAPI] 收到消息！" + message.toString());
        //1.获取用户信息
        User user = (User) session.getAttributes().get("user");
        if(user == null) {
            System.out.println("[WebSocketAPI] user == null！用户未登录，无法进行消息转发");
            return;
        }
        //2.对请求进行解析，把json请求转变为java对象
        MessageRequest req = objectMapper.readValue(message.getPayload(),MessageRequest.class);
        if(req.getType().equals("message")) {
            //正确，进行消息转发
            transferMessage(user,req);
        }else {
            System.out.println("[WebSocketAPI] req.type有误" + message.getPayload());
        }
    }

    /**
     * 通过该方法，完成消息转发
     * @param fromUser
     * @param req
     */
    private void transferMessage(User fromUser, MessageRequest req) throws IOException {
        //1.先构造一个待转发响应对象
        MessageResponse resp = new MessageResponse();
        resp.setType("message");
        resp.setFromId(fromUser.getUserId());
        resp.setFromName(fromUser.getUsername());
        resp.setSessionId(req.getSessionId());
        resp.setContent(req.getContent());
        //将java转化为json
        String respJson = objectMapper.writeValueAsString(resp);
        System.out.println("[transferMessage] respJson: " + respJson);
        //2.根据请求中的sessionId,获取到有那些用户（查询数据库）
        List<Friend> friends = messageSessionMapper.getFriendsBySessionId(req.getSessionId(), fromUser.getUserId());
        Friend myself = new Friend();
        myself.setFriendId(fromUser.getUserId());
        myself.setFriendName(fromUser.getUsername());
        friends.add(myself);
        //3.遍历列表，将响应依次发给每个存在的用户+自己本身
        for (Friend friend : friends) {
            WebSocketSession webSocketSession = onlineUserManger.getSession(friend.getFriendId());
            //用户不在线，跳过
            if(webSocketSession == null) {
                continue;
            }
            webSocketSession.sendMessage(new TextMessage(respJson));
        }
        //4.将消息存放在数据库中，便于查询历史消息（如果用户不在线，但是存储在了数据库，当用户上线，就可以收到消息）
        Message message = new Message();
        message.setFromId(fromUser.getUserId());
        message.setSessionId(req.getSessionId());
        message.setContent(req.getContent());
        messageMapper.add(message);
    }

    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        //webSocket连接出现异常后自动调用
        System.out.println("[WebSocketAPI] 连接异常！" + exception.toString());
        //下线
        User user = (User) session.getAttributes().get("user");
        if(user == null) {
            return;
        }
        //上线
        onlineUserManger.offline(user.getUserId(),session);
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        //webSocket连接正常关闭后自动调用
        System.out.println("[WebSocketAPI] 连接关闭！" + status.toString());
        //下线
        User user = (User) session.getAttributes().get("user");
        if(user == null) {
            return;
        }
        //上线
        onlineUserManger.offline(user.getUserId(),session);
    }
}
